package site.lanmushan.framework.authorization;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import site.lanmushan.framework.authorization.strategy.ContextStorageStrategy;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author Administrator
 */
@Slf4j
public class SignFilterManager {
    private final CopyOnWriteArrayList<Authority> staticAuthorityList = new CopyOnWriteArrayList<>();
    final PathMatcher pathMatcher = new AntPathMatcher();
    @Autowired
    private ContextStorageStrategy contextStorageStrategy;

    public SignFilterManager(List<Authority> authorities) {
        if (authorities == null) {
            return;
        }
        staticAuthorityList.addAll(authorities);
    }

    public SignFilterManager() {
    }


    public Boolean allow(String targetUri, String token) {
        CurrentUser currentUser = CurrentUserUtil.getCurrentUser(token);
        //判断静态文件中授权允许的列表
        for (Authority authority : staticAuthorityList) {
            Boolean result = pathMatcher.match(authority.getUrl(), targetUri);
            if (!result) {
                continue;
            }
            if (authority.getRoleCodes().contains(CurrentUserUtil.ANON_CODE)) {
                return true;
            } else if (authority.getRoleCodes().containsAll(currentUser.getRoleCodes())) {
                return true;
            }
        }
        //判断动态权限列表
        for (Authority authority : contextStorageStrategy.getMatcherPermissionAuthority()) {
            Boolean result = pathMatcher.match(authority.getUrl(), targetUri);
            if (!result) {
                continue;
            }
            if (authority.getRoleCodes().contains(CurrentUserUtil.ANON_CODE)) {
                return true;
            } else if (authority.getRoleCodes().containsAll(currentUser.getRoleCodes())) {
                return true;
            }
        }
        //判断是不是指定url，不然所有的都判断性能太低
        if (CurrentUserUtil.currentUserHasUriPermissions(targetUri, currentUser)) {
            return true;
        }

        //判断登录信息过期
        if (!CurrentUserUtil.isLoginOverdue(currentUser, token)) {
            return false;
        }
        //判断是不是admin角色
        if (currentUser != null && currentUser.isAdmin()) {
            return true;
        }
        return false;
    }

    public void registerUrl(String url, String roleCodes[], Integer order) {
        Authority authority = new Authority();
        authority.setOrder(order);
        authority.setRoleCodes(Arrays.asList(roleCodes));
        authority.setUrl(url);
        this.registerUrl(authority);
    }

    public void registerUrl(Authority authority) {
        this.staticAuthorityList.add(authority);
        this.staticAuthorityList.stream().sorted((a, b) -> {
            return a.getOrder() - b.getOrder();
        });
    }

    public void removeUrl(String url) {
        this.staticAuthorityList.remove(url);
    }

}

